#!/usr/bin/python
# -*- coding: utf-8 -*-
# @version        : 1.0
# @Creaet Time    : 2021/10/18 22:19 
# @File           : database.py
# @IDE            : PyCharm
# @desc           : SQLAlchemy 部分

"""
导入 SQLAlchemy 部分

安装： pip install sqlalchemy
"""
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker


"""
为 SQLAlchemy 创建数据库 URL

连接 SQLite 数据库 URL（用 SQLite 数据库打开一个文件）

该文件将位于文件中的同一目录中sql_app.db，这就是为什么最后一部分是./sql_app.db
"""
SQLALCHEMY_DATABASE_URL = "sqlite:///./sql_app.db"
"""连接 postgresql 数据库方式"""
# SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
"""连接 mysql 数据库方式"""
# SQLALCHEMY_DATABASE_URL = "mysql://user:password@postgresserver/db"


"""
创建一个 SQLAlchemy『引擎』

echo=True：引擎将会把执行的SQL语句打印到控制台，引擎将用repr()函数记录所有语句及其参数列表到日志

由于SQLAlchemy是多线程，指定check_same_thread=False来让建立的对象任意线程都可使用。这个参数只在用SQLite数据库时设置

信息：
默认情况下，假定每个线程将处理一个独立的请求，SQLite 仅允许一个线程与其通信。
这是为了防止为不同的事物（针对不同的请求）意外共享同一连接。
但是在 FastAPI 中，使用正常功能（def），一个以上的线程可以与同一请求的数据库交互，因此我们需要使 SQLite 知道它应该允许使用 connect_args = {“ check_same_thread”：False}。
此外，我们将确保每个请求在依赖关系中都有自己的数据库连接会话，因此不需要该默认机制。
"""
engine = create_engine(
    SQLALCHEMY_DATABASE_URL, encoding='utf-8', echo=False, connect_args={"check_same_thread": False}
)


"""
在 SQLAlchemy 中，CRUD都是通过会话(session)进行的，所以我们必须要先创建会话。

SessionLocal 类的每个实例将是一个数据库会话。该类本身不是数据库会话。

autoflush：开启就是在查询操作之前，会将同一个事务内积累的sql自动发送给mysql执行，那么当前的查询结果就会包括了同一个事务内累积sql执行操作结果，但是这些累积sql操作并没有提交。 
关闭就是不会把累积的sql发送过去，当前的查询操作只是查询了所有已经提交的数据，sqlalchemy 默认为 True，不建议为True

autocommit：是否自动提交事务，这个值是关闭的，那么项目不会自动提交事务，需要手动提交事务。如果这个值是开启的，说明每个sql都是自动提交事务。sqlalchemy 默认为False，也建议为False

bind 绑定 SQLAlchemy『引擎』

当 expire_on_commit=True 时，commit 之后所有实例都会过期，之后再访问这些过期实例的属性时，SQLAlchemy 会重新去数据库加载实例对应的数据记录。
"""
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine, expire_on_commit=True)


"""
创建基本映射类

稍后，我们将继承该类，创建每个 ORM 模型
"""
Model = declarative_base(bind=engine, name='Model')


""" 附上三个SQLAlchemy教程

SQLAlchemy的基本操作大全
    http://www.taodudu.cc/news/show-175725.html

Python3+SQLAlchemy+Sqlite3实现ORM教程
    https://www.cnblogs.com/jiangxiaobo/p/12350561.html

SQLAlchemy基础知识 Autoflush和Autocommit
    https://www.jianshu.com/p/b219c3dd4d1e
"""